package com.scs.application.modules.upms.controller;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.model.*;
import com.scs.application.core.mvc.controller.CrudController;
import com.scs.application.core.mvc.controller.ImAndExAbleController;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UserUtils;
import com.scs.application.modules.design.service.QueryGenerator;
import com.scs.application.modules.upms.entity.Office;
import com.scs.application.modules.upms.entity.User;
import com.scs.application.modules.upms.mapper.OfficeMapper;
import com.scs.application.modules.upms.mapper.UserMapper;
import com.scs.application.modules.upms.request.OfficeQueryRequest;
import com.scs.application.modules.upms.security.UserPrincipal;
import com.scs.application.modules.upms.service.OfficeService;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 机构 controller
 *
 */
@AllArgsConstructor
@RestController
@RequestMapping("/upms/offices")
public class OfficeController extends CrudController<Office, String, OfficeService> implements ImAndExAbleController<OfficeQueryRequest> {
    private OfficeMapper officeMapper;
    private UserMapper userMapper;


    @GetMapping("/page")
    public PageResult page(OfficeQueryRequest request) {
        IPage page = service.page(request);
        return PageResult.ok("查询成功", page.getRecords(), page.getTotal());
    }

    @GetMapping("/list")
    public CommonResult list(OfficeQueryRequest request) {
        List<Office> list = service.list(Wrappers.<Office>query().orderByDesc("gmt_modified"));
        return CommonResult.ok("查询成功", list);
    }

    @GetMapping("/tree")
    public CommonResult tree(OfficeQueryRequest request) {
        List<Office> list;
        UserPrincipal user = UserUtils.currentUser();
        if (!user.isAdmin() && StringUtils.isBlank(request.getParentId())) {
            list = service.list(Wrappers.<Office>query().in("id", service.getOfficeParents(user.getOfficeId(), true)));
            request.setAutoAddRoot(false);
        } else {
            list = service.list(request);
        }
//        list = service.list(request);
        TreeNode root = null;
        if (request.isAutoAddRoot()) {
            root = new TreeNode();
            root.setId("0");
            root.setTitle("组织机构");
        }
        TreeModel<Office> treeModel = new TreeModel<Office>(list, "name", root);
        return CommonResult.ok("查询成功", treeModel.asList());
    }

    /***
     * @param request
     * @Description:  通用分页
     */
    @Override
    @GetMapping("/pageCommon")
    public PageResult pageCommon(HttpServletRequest request, Office entity) {
        IPage<Office> page = QueryGenerator.parsePage(request);
        QueryWrapper<Office> queryWrapper = QueryGenerator.initQueryWrapper(request);
        fillQueryAuth(queryWrapper,entity);
        IPage<Office> pageResult = officeMapper.pageCommon(page, queryWrapper);
        if (pageResult.getTotal() > 0) {
            pageResult.getRecords().stream().forEach(item -> {
                if (StringUtils.isBlank(item.getParentName()) && (StringUtils.isBlank(item.getParentId()) || "0".equals(item.getParentId()))) {
                    item.setParentName("组织机构");
                }
            });
        }
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }

    /***
     * @param entity
     * @Description:  通用保存、更新
     */
    @Override
    @PostMapping("/saveOrUpdateCommon")
    public RestResult saveOrUpdateCommon(@Valid @RequestBody Office entity) {
        boolean isOk = service.saveOrUpdate(entity);
        if (!isOk) {
            return RestResult.error("数据保存失败");
        }
        fillData(entity);
        return RestResult.ok("数据保存成功", entity);
    }

    /***
     * @param id
     * @Description:  通用查找，单个
     */
    @Override
    @GetMapping("/findByIdCommon")
    public RestResult findByIdCommon(@RequestParam("id") Serializable id) {
        Office entity = service.getById(id);
        if (entity == null) {
            return RestResult.error("数据查询失败<br>可能所操作数据已被删除，请刷新后重新尝试操作");
        }
        fillData(entity);
        return RestResult.ok("获取数据成功", entity);
    }

    private void fillData(Office entity) {
        if (StringUtils.isBlank(entity.getParentName()) && (StringUtils.isBlank(entity.getParentId()) || "0".equals(entity.getParentId()))) {
            entity.setParentName("全部机构");
            return;
        }
        Office parent =  service.getById(entity.getParentId());
        if (parent == null) {
            return;
        }
        entity.setParentName(parent.getName());
    }

    /***
     * @Description:  通用删除，多个
     */
    @DeleteMapping("/deleteBatchCommon")
    @Override
    public RestResult deleteBatchCommon(@RequestBody Map<String, Object> para) {
        List<Serializable> ids = (List<Serializable>) para.get("ids");
        Collection<Office> list =  service.listByIds(ids);
        if (list == null || ObjectUtil.length(list) != ObjectUtil.length(ids)) {
            return RestResult.error("数据删除失败<br>可能所操作数据已被删除，请刷新页面重新尝试操作");
        }
        List<Office> childList = service.list(Wrappers.<Office>query().in("parent_id", ids));
        if (ObjectUtil.length(childList) > 0) {
            BusinessException.throwError("机构[{}]，存在下级节点[{}]，不允许删除",
                    list.stream().filter(tmp -> tmp.getId().equals(childList.get(0).getParentId())).findFirst().get().getName(),
                    childList.get(0).getName());
        }

        User user = userMapper.selectOne(Wrappers.<User>query().in("office_id", ids).last("limit 1"));

        if (user != null) {
            BusinessException.throwError("机构[{}]，存在用戶[{}]，不允许删除",
                    list.stream().filter(tmp -> tmp.getId().equals(user.getOfficeId())).findFirst().get().getName(),
                    user.getNickname());
        }

        Boolean isOk = service.removeByIds(ids);
        if (!isOk) {
            return RestResult.error("数据删除失败<br>可能所操作数据已被删除，请刷新页面重新尝试操作");
        }

        return RestResult.ok("数据删除成功");
    }


}
